package com.example.elderlycare.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.elderlycare.controller.entity.RelativeRequestBody;
import com.example.elderlycare.dao.entity.Relative;
import com.example.elderlycare.service.RelativeService;
import com.example.elderlycare.service.entity.RelativeListResponseBody;
import com.example.elderlycare.utils.Result;
import com.example.elderlycare.utils.ResultEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.List;

@RestController
@RequestMapping("/relative")
@Slf4j
public class RelativeController {

    @Resource
    RelativeService relativeService;

    /**
     * 根据老人 id 查询对应家属信息
     *
     * @param elderId 老人的id
     * @return RelativeListResponseBody
     */
    @GetMapping("/query")
    public Result<RelativeListResponseBody> queryRelativesByElderId(
            @RequestParam("elderId") @NotBlank Integer elderId) {
        try {
            RelativeListResponseBody res = relativeService.getRelativesByElderId(elderId);
            return Result.success(res);
        } catch (Exception e) {
            log.warn("Exception", e);
            return Result.error(ResultEnum.DEFAULT_ERROR);
        }
    }

    /**
     * 增加老人家属
     *
     * @param req RelativeRequestBody.addRelative
     * @return null
     */
    @PostMapping("/add")
    public Result<?> addRelative(@RequestBody RelativeRequestBody.addRelative req) {
        Relative relative = Relative.builder()
                .name(req.getName())
                .elderId(req.getElderId())
                .phone(req.getPhone())
                .number(req.getNumber())
                .relationId(req.getRelationId())
                .certificateId(req.getCertificateId())
                .build();
        /* 查找当前优先级最低的亲属 */
        QueryWrapper<Relative> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("elder_id", req.getElderId()).orderByDesc("priority").last("limit 1");
        Relative prevRelative = relativeService.getOne(queryWrapper);
        if (prevRelative == null) {
            relative.setPriority(1);
        } else {
            relative.setPriority(prevRelative.getPriority() + 1);
        }
        try {
            boolean save = relativeService.save(relative);
            if (save) {
                return Result.success("null");
            } else {
                log.warn("add relative error");
                return Result.error(ResultEnum.DEFAULT_ERROR);
            }
        } catch (Exception e) {
            log.warn("Exception", e);
            return Result.error(ResultEnum.DEFAULT_ERROR);
        }

    }

    /**
     * 修改老人亲属信息
     *
     * @param req RelativeRequestBody.updateRelative
     * @return null
     */
    @PutMapping("/update")
    public Result<?> updateRelative(@RequestBody RelativeRequestBody.updateRelative req) {
        Relative relative = Relative.builder()
                .id(req.getId())
                .name(req.getName())
                .elderId(req.getElderId())
                .phone(req.getPhone())
                .number(req.getNumber())
                .relationId(req.getRelationId())
                .certificateId(req.getCertificateId())
                .build();
        try {
            boolean flag = relativeService.updateById(relative);
            if (flag) {
                return Result.success("null");
            } else {
                log.warn("update relative error");
                return Result.error(ResultEnum.DEFAULT_ERROR);
            }
        } catch (Exception e) {
            log.warn("Exception", e);
            return Result.error(ResultEnum.DEFAULT_ERROR);
        }
    }

    /**
     * 删除老人亲属信息
     *
     * @param id 需要删除亲属的id
     * @return null
     */
    @DeleteMapping("/delete")
    public Result<?> deleteRelative(@RequestParam("id") @NotEmpty Integer id) {
        try {
            /* 获取当前亲属信息 */
            Relative curr = relativeService.getById(id);
            QueryWrapper<Relative> queryWrapper = new QueryWrapper<>();
            /* 找出比该亲属优先级低的亲属，优先级均上调 1 */
            queryWrapper.eq("elder_id", curr.getElderId()).gt("priority", curr.getPriority());
            List<Relative> relatives = relativeService.list(queryWrapper);
            if (relatives != null) {
                relatives.forEach(relative -> relative.setPriority(relative.getPriority() - 1));
                relativeService.updateBatchById(relatives);
            }
            boolean flag = relativeService.removeById(id);
            if (flag) {
                return Result.success("null");
            } else {
                log.warn("delete relative error");
                return Result.error(ResultEnum.DEFAULT_ERROR);
            }
        } catch (Exception e) {
            log.warn("Exception", e);
            return Result.error(ResultEnum.DEFAULT_ERROR);
        }
    }

    /**
     * 当前亲属与邻近亲属(上邻/下邻)交换优先级
     *
     * @param req changePriority
     * @return null
     */
    @PutMapping("/change_priority")
    public Result<?> changePriority(@RequestBody RelativeRequestBody.changePriority req) {
        try {
            /* 获取当前亲属信息 */
            Relative curr = relativeService.getById(req.getId());
            /* 参数 up 为 1 则当前亲属优先级往上调整一级，否则往下调一级 */
            int diff = req.getUp() == 1 ? -1 : 1;
            QueryWrapper<Relative> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("elder_id", curr.getElderId()).eq("priority", curr.getPriority() + diff);
            Relative nearbyRelative = relativeService.getOne(queryWrapper);
            int currPriority = curr.getPriority();
            curr.setPriority(nearbyRelative.getPriority());
            nearbyRelative.setPriority(currPriority);
            if (relativeService.updateById(curr) && relativeService.updateById(nearbyRelative)) {
                return Result.success(null);
            } else {
                return Result.error(ResultEnum.DEFAULT_ERROR);

            }
        } catch (Exception e) {
            log.warn("Exception", e);
            return Result.error(ResultEnum.DEFAULT_ERROR);
        }
    }
}
